<template>
	<view
		class="xt-form-item-main"
		:class="{
			'xt-form-item-disabled': disabled
		}"
		:style="{
			borderBottom: propsData.borderBottom ? '1px solid #e5e5e5' : 'none'
		}"
	>
		<view
			class="xt-form-item"
			:class="formClass"
			:style="{
				padding: `${handlePixel(propsData.gap)} 0`
			}"
		>
			<view
				class="xt-form-label"
				v-if="label"
				:style="{
					width: handlePixel(labelWidth || propsData.labelWidth || 'auto'),
					...propsData.labelStyle
				}"
			>
				<view class="xt-form-text">
					{{ label }}
					<view class="xt-form-label-required" v-if="required">*</view>
				</view>
			</view>
			<view class="xt-form-content">
				<slot></slot>
			</view>
		</view>
		<view
			class="xt-form-tips"
			:style="{
				paddingLeft: handlePixel(labelWidth || propsData.labelWidth, 'px', '30rpx', '+')
			}"
			v-if="message"
		>
			{{ message }}
		</view>
	</view>
</template>
<script>
import props from './props.js';
/**
 * Form 表单
 * @description 本组件依附于 xt-form 使用，用于表单布局
 * @tutorial https://ext.dcloud.net.cn/plugin?name=xt-form
 *
 * @property {String}          		label             		表单项标题
 * @property {String}          		prop             		表单项字段
 * @property {String | Number}      labelWidth             	表单项标题宽度
 * @property {Boolean}          	required             	是否显示 * 号(默认 false)
 * @property {Boolean}          	disabled             	是否禁用表单项(默认 false)
 * @example <xt-form><xt-form-item><xt-input></xt-input></xt-form-item></xt-form>
 */
export default {
	name: 'xt-form-item',
	mixins: [props],
	data() {
		return {
			propsData: {},
			message: ''
		};
	},
	computed: {
		// 表单样式
		formClass() {
			const css = [];
			css.push('xt-form-item-' + this.propsData.labelAlign);
			return css;
		}
	},
	beforeDestroy() {
		if (this.parent && this.array(this.parent.children)) {
			const childrenList = this.parent.children;
			childrenList.map((child, index) => {
				if (child === this) {
					childrenList.splice(index, 1);
				}
			});
		}
	},
	methods: {
		handlePixel(value = 'auto', unit = 'px', count, type) {
			const unitRegex = /^(\d+(\.\d+)?)([a-zA-Z%]+)?$/;
			let valueNum = value;
			let valueUnit = unit;
			let countNum = count;
			let countUnit = unit;
			let result = value;

			// 处理 value 参数
			if (typeof value === 'string' && unitRegex.test(value)) {
				const valueMatch = value.match(unitRegex);
				valueNum = Number(valueMatch[1]); // 数字部分
				result = valueNum; // 初始结果是数字部分
				valueUnit = valueMatch[3] || unit; // 单位部分（如果有）
			}

			// 处理 count 参数
			if (typeof count === 'string' && unitRegex.test(count)) {
				const countMatch = count.match(unitRegex);
				countNum = Number(countMatch[1]); // 数字部分
				countUnit = countMatch[3] || unit; // 单位部分
			}

			// 进行相应的运算
			if (valueNum > 0 && countNum > 0) {
				switch (type) {
					case '+':
						result = valueNum + countNum;
						break;
					case '-':
						result = valueNum - countNum;
						break;
					case '*':
						result = valueNum * countNum;
						break;
					case '/':
						result = valueNum / countNum;
						break;
				}
			}

			// 返回结果时，附上单位部分
			return result + (valueUnit || '');
		},
		array(value) {
			if (typeof Array.isArray === 'function') {
				return Array.isArray(value);
			}
			return Object.prototype.toString.call(value) === '[object Array]';
		},
		// 更新父组件的model
		updateParentModel(value) {
			this.$set(this.propsData, 'model', value);
		},
		// 获取父组件
		getParent(name = undefined) {
			let parent = this.$parent;
			while (parent) {
				// 父组件
				if (parent.$options && parent.$options.name !== name) {
					// 如果组件的name不相等，继续上一级寻找
					parent = parent.$parent;
				} else {
					return parent;
				}
			}
			return false;
		},
		getParentData(parentName = '') {
			// 避免在created中去定义parent变量
			if (!this.parent) this.parent = {};
			this.parent = this.getParent.call(this, parentName);
			if (this.parent.children) {
				// 如果父组件的children不存在本组件的实例，才将本实例添加到父组件的children中
				this.parent.children.indexOf(this) === -1 && this.parent.children.push(this);
			}
			const parent = this.parent;
			this.propsData = {
				value: parent.model,
				labelWidth: parent.labelWidth,
				labelAlign: parent.labelAlign,
				labelStyle: parent.labelStyle,
				borderBottom: parent.borderBottom,
				gap: parent.gap
			};
		},
		/**
		 * @description 获取某个对象下的属性
		 * @param {object} obj 对象
		 * @param {string} key 需要获取的属性字段
		 * @returns {*}
		 */
		getProperty(obj, key) {
			if (!obj) {
				return;
			}
			if (typeof key !== 'string' || key === '') {
				return '';
			}
			if (key.indexOf('.') !== -1) {
				const keys = key.split('.');
				let firstObj = obj[keys[0]] || {};

				for (let i = 1; i < keys.length; i++) {
					if (firstObj) {
						firstObj = firstObj[keys[i]];
					}
				}
				return firstObj;
			}
			return obj[key];
		},
		/**
		 * @description 设置对象的属性值，如果'a.b.c'的形式进行设置
		 * @param {object} obj 对象
		 * @param {string} key 需要设置的属性
		 * @param {string} value 设置的值
		 */
		setProperty(obj, key, value) {
			if (!obj) {
				return;
			}
			// 递归赋值
			const inFn = function (_obj, keys, v) {
				// 最后一个属性key
				if (keys.length === 1) {
					_obj[keys[0]] = v;
					return;
				}
				// 0~length-1个key
				while (keys.length > 1) {
					const k = keys[0];
					if (!_obj[k] || typeof _obj[k] !== 'object') {
						_obj[k] = {};
					}
					const key = keys.shift();
					// 自调用判断是否存在属性，不存在则自动创建对象
					inFn(_obj[k], keys, v);
				}
			};

			if (typeof key !== 'string' || key === '') {
			} else if (key.indexOf('.') !== -1) {
				// 支持多层级赋值操作
				const keys = key.split('.');
				inFn(obj, keys, value);
			} else {
				obj[key] = value;
			}
		},
		// 移除校验结果
		clearValidate() {
			this.message = null;
		},
		// 清空当前的组件的校验结果，并重置为初始值
		resetField() {
			// 找到原始值
			const value = this.getProperty(this.parent.oldData, this.prop);
			// 将u-form的model的prop属性链还原原始值
			this.setProperty(this.parent.model, this.prop, value);
			// 移除校验结果
			this.message = null;
		}
	},
	mounted() {
		this.getParentData('xt-form');
	}
};
</script>
<style scoped lang="scss">
@import './style.scss';
</style>
